﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using WorldMap;
using FileMode = System.IO.FileMode;
using Random = UnityEngine.Random;

namespace WorldMapTools
{
    public class GeneralTileEditor : EditorWindow
{
    public int GridX;
    public int GridY;
    public const int TILE_WIDTH = 360;
    public const int TILE_HEIGHT = 360;
    
    public static string[] prefabs = new []{"tile_1.prefab","tile_2.prefab","tile_3.prefab","tile_4.prefab","tile_5.prefab","tile_6.prefab","tile_7.prefab","tile_8.prefab","tile_9.prefab","tile_10.prefab"};
   
   // [MenuItem("Tools/Map/GeneralTilesDataT")]
    public static void TestGeneralTilesJson()
    {
        var tileSetData = AssetDatabase.LoadAssetAtPath<TileSetData>("Assets/ResourcesAssets/World/mapdata/tiles.asset");
  
    }

   // [MenuItem("Tools/Map/GeneralTilesData_scriptObject")]
    public static void GeneralTilesScriptObject()
    {
        Dictionary<string, TileData> tils = new Dictionary<string, TileData>();
        var dir = Directory.GetFiles(Application.dataPath + "/Arts/world/prefabs/tiles");
        foreach (var pt in dir)
        {
            if (pt.Contains(".meta")) continue;
            var tileData = new TileData(Path.GetFileNameWithoutExtension(pt));
            tils.Add(tileData.name,tileData);
            var path = pt.SanitizePath().Replace(Application.dataPath, "Assets");
            var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(path);
            var childCount =  gameObject.transform.childCount;
            if (childCount > 0)
            {

                for (int i = 0; i < childCount; i++)
                {
                    var transform = gameObject.transform.GetChild(i);
                    var ptx = PrefabUtility.GetPrefabType(transform.gameObject);
                    var pat = PrefabUtility.GetPrefabAssetType(transform.gameObject);
                    if (PrefabUtility.GetPrefabType(transform.gameObject) == PrefabType.Prefab)
                    {
                        var assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(transform.gameObject);
                        var assetName = Path.GetFileNameWithoutExtension(assetPath);
                        TileElementsData tileElementData = tileData.GetOrCreateElementListByName(assetName);
                        var tileElementsProperty = new TileElementsProperty(transform.localPosition,transform.localRotation.eulerAngles,transform.localScale);
                        tileElementData.addElementProperty(tileElementsProperty);

                    }
                   
                }
            }
        }

        TileSetData tileSetData = ScriptableObject.CreateInstance<TileSetData>();
        tileSetData.SetData(tils.Values.ToList());
        AssetDatabase.CreateAsset(tileSetData,"Assets/Arts/world/mapdata/tiles.asset");
    }
    //[MenuItem("Tools/Map/GeneralTilesData")]
    public static void GeneralTilesJson()
    {
         Dictionary<string, TileData> tils = new Dictionary<string, TileData>();
        var dir = Directory.GetFiles(Application.dataPath + "/Arts/world/prefabs/tiles");
        foreach (var pt in dir)
        {
            if (pt.Contains(".meta")) continue;
            var tileData = new TileData(Path.GetFileNameWithoutExtension(pt));
            tils.Add(tileData.name,tileData);
            var path = pt.SanitizePath().Replace(Application.dataPath, "Assets");
            var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(path);
            var childCount =  gameObject.transform.childCount;
            if (childCount > 0)
            {
                
                for (int i = 0; i < childCount; i++)
                {
                    var transform = gameObject.transform.GetChild(i);
                    var ptx = PrefabUtility.GetPrefabType(transform.gameObject);
                    var pat = PrefabUtility.GetPrefabAssetType(transform.gameObject);
                    if (PrefabUtility.GetPrefabType(transform.gameObject) == PrefabType.Prefab)
                    {
                        var assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(transform.gameObject);
                        var assetName = Path.GetFileNameWithoutExtension(assetPath);
                        TileElementsData tileElementData = tileData.GetOrCreateElementListByName(assetName);
                        var tileElementsProperty = new TileElementsProperty(transform.localPosition,transform.localRotation.eulerAngles,transform.localScale);
                        tileElementData.addElementProperty(tileElementsProperty);
                    }
                   
                }
            }
        }

        var jsonstr = SerializTileDatas(tils);
        FileStream f = File.Open(Path.Combine(Application.dataPath, "Arts/world/mapdata/tiles.txt").SanitizePath(),
            FileMode.OpenOrCreate);
        var ba = Encoding.UTF8.GetBytes(jsonstr);
        f.Write(ba,0,ba.Length);
        f.Close();
    }
    private static string SerializTileDatas(Dictionary<string, TileData> tils)
    {
        
        byte[] b1 = {0x01}; // 切割属性
        byte[] b2 = {0x02}; // 切割属性集合
        byte[] b3 = {0x03}; //切割tileelement
        byte[] b4 = {0x04}; //切割tile
        byte[] b5 = {0x05}; 
        string attrSep = Encoding.ASCII.GetString(b1);
        string elementItemSep = Encoding.ASCII.GetString(b2);
        string tileElementSep = Encoding.ASCII.GetString(b3);
        string tileSep = Encoding.ASCII.GetString(b4);
        string s5 = Encoding.ASCII.GetString(b5);
        var resultstr = new StringBuilder();
        foreach (var tileData in tils.Values)
        {
            resultstr.Append(tileData.name);
            resultstr.Append(tileSep);
            for (var i = 0 ; i < tileData.Keys.Count; i++)
            {
                var elementsName = tileData.Keys[i];
                var elementsData = tileData.elements[i];
                resultstr.Append(elementsName);
                resultstr.Append(tileElementSep);
                foreach (var property in elementsData.properties)
                {

                    resultstr.Append(property.position.x.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.position.y.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.position.z.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.rotation.x.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.rotation.y.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.rotation.z.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.scale.x.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.scale.y.ToString("F"));
                    resultstr.Append(attrSep);
                    resultstr.Append(property.scale.z.ToString("F"));
                    resultstr.Append(elementItemSep);
                }
            }
            
        }

        return resultstr.ToString();
    }

    //[MenuItem("Tools/Map/GeneralMap_ScriptObject")]
    public static void GeneralMapScriptObject()
    {
        var mapData = ScriptableObject.CreateInstance<MapData>();
        mapData.XNum = 100;
        mapData.YNum = 100;
        mapData.TileWidth = TILE_WIDTH;
        mapData.TileHeight = TILE_HEIGHT;
        var mapPrefab = (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Arts/world/prefabs/Map01.prefab");
        var childCount =  mapPrefab.transform.childCount;
        if (childCount > 0)
        {
                
            for (int i = 0; i < childCount; i++)
            {
                var transform = mapPrefab.transform.GetChild(i);
                if (PrefabUtility.GetPrefabType(transform.gameObject) == PrefabType.Prefab)
                {
                    var assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(transform.gameObject);
                    var assetName = Path.GetFileNameWithoutExtension(assetPath);
                    mapData.tiles.Add(assetName);
                }
                   
            }
        }
        AssetDatabase.CreateAsset(mapData,"Assets/Arts/world/mapdata/map_01.asset");
    }
    
    //[MenuItem("Tools/Map/GeneralMapPrefab")]
    public static void TestGeneralPrefab()
    {
        GeneralTiles(50, 50);
        
    }
    
    
    private static void GeneralTiles(int wSize,int hSize)
    {


        //var prefab = (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Arts/world/Map01.prefab");
        //var root = Instantiate(prefab).transform;
        var root = new GameObject("Map01").transform;
        var tilesPrefabs = new List<GameObject>();
        for (int i = 0; i < prefabs.Length; i++)
        {
            var path = "Assets/ResourcesAssets/World/prefabs/tiles/" + prefabs[i];
            tilesPrefabs.Add((GameObject)AssetDatabase.LoadAssetAtPath<GameObject>(path));
        }
        for (int y = 0; y < hSize; y++)
        {
            for (int x = 0,count = 0; x < wSize; x++,count++)
            {
                var tilePrefab = tilesPrefabs[Random.Range(0, tilesPrefabs.Count)];
                var tile = Instantiate(tilePrefab, root);
                tile = PrefabUtility.ConnectGameObjectToPrefab(tile, tilePrefab);
                tile.transform.localPosition = new Vector3(x*TILE_WIDTH,0,y*TILE_HEIGHT);
            }
        }
        
        PrefabUtility.SaveAsPrefabAssetAndConnect(root.gameObject, "Assets/ResourcesAssets/World/prefabs/Map01.prefab",
            InteractionMode.AutomatedAction);
    }

    private static GameObject getPrefab(int index)
    {
        Assert.IsTrue(prefabs.Length > 0,"prefabs不包含元素");
        if (index > -1 && index < prefabs.Length)
        {
            return (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/ResourcesAssets/World/prefabs/tiles/"+prefabs[index]);
        }
        else
        {
            return (GameObject)AssetDatabase.LoadAssetAtPath<GameObject>("Assets/ResourcesAssets/World/prefabs/tiles/tile_1.prefab");
        }
       
    }
    
    
}

}
